#include "task_entity.h"

namespace kernel {
namespace task {

TaskEntity::TaskEntity(
    const std::string& taskId,
    TaskType type,
    int agvNumber)
    : m_taskId(taskId)
    , m_type(type)
    , m_agvNumber(agvNumber)
    , m_createTime(std::chrono::system_clock::now())
{
}

// ==================== 业务方法 ====================

bool TaskEntity::start()
{
    if (!canStart()) {
        return false;
    }

    m_status = TaskStatus::Running;
    m_startTime = std::chrono::system_clock::now();
    m_errorMessage.clear();

    return true;
}

bool TaskEntity::pause()
{
    if (!canPause()) {
        return false;
    }

    m_status = TaskStatus::Paused;
    return true;
}

bool TaskEntity::resume()
{
    if (!canResume()) {
        return false;
    }

    m_status = TaskStatus::Running;
    return true;
}

void TaskEntity::complete()
{
    m_status = TaskStatus::Completed;
    m_endTime = std::chrono::system_clock::now();
}

void TaskEntity::cancel()
{
    m_status = TaskStatus::Cancelled;
    m_endTime = std::chrono::system_clock::now();
}

void TaskEntity::fail(const std::string& errorMessage)
{
    m_status = TaskStatus::Failed;
    m_errorMessage = errorMessage;
    m_endTime = std::chrono::system_clock::now();
}

bool TaskEntity::canStart() const
{
    return m_status == TaskStatus::Pending;
}

bool TaskEntity::canPause() const
{
    return m_status == TaskStatus::Running;
}

bool TaskEntity::canResume() const
{
    return m_status == TaskStatus::Paused;
}

bool TaskEntity::isTerminated() const
{
    return m_status == TaskStatus::Completed ||
           m_status == TaskStatus::Failed ||
           m_status == TaskStatus::Cancelled;
}

double TaskEntity::getElapsedSeconds() const
{
    if (m_status == TaskStatus::Pending) {
        return 0.0;
    }

    auto endTime = m_endTime;
    if (!isTerminated()) {
        endTime = std::chrono::system_clock::now();
    }

    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
        endTime - m_startTime
    );

    return duration.count() / 1000.0;
}

void TaskEntity::setMetadata(const std::string& key, const std::string& value)
{
    m_metadata[key] = value;
}

std::string TaskEntity::getMetadata(const std::string& key) const
{
    auto it = m_metadata.find(key);
    if (it != m_metadata.end()) {
        return it->second;
    }
    return "";
}

} // namespace task
} // namespace kernel
